//! # 文件存储增强功能测试
//!
//! 测试完善后的文件存储功能，包括分片存储、索引管理、查询和清理功能

use rustcloud_bus::{
    file_storage::{FileStorage, FileStorageConfig},
    persistence::{MessageRecord, MessageStatus, QueryCriteria, OrderBy, SortOrder, MessageStorage},
    message::Message,
};
use serde_json::json;
use std::path::PathBuf;
use tempfile::TempDir;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化日志
    tracing_subscriber::registry()
        .with(tracing_subscriber::fmt::layer().with_target(false))
        .with(EnvFilter::from_default_env().add_directive("rustcloud_bus=debug".parse()?))
        .init();

    println!("🗂️  文件存储增强功能测试开始\n");

    // 创建临时目录
    let temp_dir = TempDir::new()?;
    println!("📁 测试目录: {}", temp_dir.path().display());

    // 1. 测试文件存储创建
    println!("\n=== 1. 创建文件存储 ===");
    let config = FileStorageConfig {
        storage_dir: temp_dir.path().to_path_buf(),
        enable_compression: true,
        shard_size: 1024 * 1024, // 1MB分片大小
        index_cache_size: 1000,
        cleanup_interval_secs: 60,
    };
    
    let storage = FileStorage::new(config).await?;
    println!("✅ 文件存储创建成功");

    // 2. 测试消息存储
    println!("\n=== 2. 测试消息存储 ===");
    let mut message_ids = Vec::new();
    
    // 存储不同类型的消息
    let messages = vec![
        ("user.events.created", json!({"user_id": "user1", "name": "Alice"})),
        ("user.events.updated", json!({"user_id": "user1", "email": "alice@example.com"})),
        ("order.events.placed", json!({"order_id": "order1", "amount": 99.99})),
        ("order.events.cancelled", json!({"order_id": "order1", "reason": "user request"})),
        ("notification.events.sent", json!({"type": "email", "to": "alice@example.com"})),
    ];
    
    for (topic, data) in messages {
        let message = Message::new(topic, data);
        let id = storage.store(message).await?;
        message_ids.push(id);
        println!("  ✓ 存储消息: {} -> {}", topic, &message_ids[message_ids.len()-1][..8]);
    }
    
    // 3. 测试消息查询
    println!("\n=== 3. 测试消息查询 ===");
    
    // 查询所有消息
    let all_messages = storage.query(QueryCriteria::default()).await?;
    println!("  📊 总消息数: {}", all_messages.len());
    
    // 按状态查询
    let pending_criteria = QueryCriteria {
        status: Some(MessageStatus::Pending),
        ..Default::default()
    };
    let pending_messages = storage.query(pending_criteria).await?;
    println!("  📋 待处理消息数: {}", pending_messages.len());
    
    // 按主题模式查询
    let user_events_criteria = QueryCriteria {
        topic_pattern: Some("user.events.*".to_string()),
        limit: Some(10),
        ..Default::default()
    };
    let user_events = storage.query(user_events_criteria).await?;
    println!("  👤 用户事件消息数: {}", user_events.len());
    
    // 按排序查询
    let sorted_criteria = QueryCriteria {
        order_by: Some(OrderBy::StoredAt(SortOrder::Descending)),
        limit: Some(3),
        ..Default::default()
    };
    let sorted_messages = storage.query(sorted_criteria).await?;
    println!("  📅 按时间倒序的前3条消息:");
    for (i, record) in sorted_messages.iter().enumerate() {
        println!("    {}. {} - {}", i+1, record.message.topic(), record.stored_at.format("%H:%M:%S"));
    }

    // 4. 测试消息状态更新
    println!("\n=== 4. 测试状态更新 ===");
    if !message_ids.is_empty() {
        let first_id = &message_ids[0];
        storage.update_status(first_id, MessageStatus::Processing).await?;
        println!("  ✓ 更新消息状态: {} -> Processing", &first_id[..8]);
        
        storage.update_status(first_id, MessageStatus::Completed).await?;
        println!("  ✓ 更新消息状态: {} -> Completed", &first_id[..8]);
    }

    // 5. 测试消息检索
    println!("\n=== 5. 测试消息检索 ===");
    for (i, id) in message_ids.iter().take(3).enumerate() {
        if let Some(record) = storage.get(id).await? {
            println!("  📄 消息 #{}: {} - {} - {:?}", 
                i+1, &id[..8], record.message.topic(), record.status);
        }
    }

    // 6. 测试事务功能
    println!("\n=== 6. 测试事务功能 ===");
    let mut tx = storage.begin_transaction().await?;
    
    let tx_message = Message::new("test.transaction", json!({"test": true}));
    let tx_id = tx.store(tx_message).await?;
    println!("  💾 事务中存储消息: {}", &tx_id[..8]);
    
    // 在事务提交前，消息应该查询不到
    if storage.get(&tx_id).await?.is_none() {
        println!("  ✓ 事务提交前消息不可见");
    }
    
    tx.commit().await?;
    
    // 事务提交后，消息应该能查询到
    if storage.get(&tx_id).await?.is_some() {
        println!("  ✓ 事务提交后消息可见");
    }

    // 7. 测试批量操作
    println!("\n=== 7. 测试批量操作 ===");
    let batch_messages = vec![
        Message::new("batch.test.1", json!({"batch": 1})),
        Message::new("batch.test.2", json!({"batch": 2})),
        Message::new("batch.test.3", json!({"batch": 3})),
    ];
    
    let batch_ids = storage.store_batch(batch_messages).await?;
    println!("  📦 批量存储 {} 条消息", batch_ids.len());
    
    // 批量删除部分消息
    let delete_ids = batch_ids.into_iter().take(2).collect();
    storage.delete_batch(delete_ids).await?;
    println!("  🗑️  批量删除 2 条消息");

    // 8. 测试清理功能
    println!("\n=== 8. 测试清理功能 ===");
    let cleaned = storage.cleanup_expired().await?;
    println!("  🧹 清理过期消息: {} 条", cleaned);

    // 9. 测试统计信息
    println!("\n=== 9. 存储统计信息 ===");
    let stats = storage.get_stats().await?;
    println!("  📊 存储统计:");
    println!("    • 总消息数: {}", stats.total_messages);
    println!("    • 待处理: {}", stats.pending_messages);
    println!("    • 处理中: {}", stats.processing_messages);
    println!("    • 已完成: {}", stats.completed_messages);
    println!("    • 失败数: {}", stats.failed_messages);
    
    if let Some(oldest) = stats.oldest_message {
        println!("    • 最旧消息: {}", oldest.format("%H:%M:%S"));
    }
    if let Some(newest) = stats.newest_message {
        println!("    • 最新消息: {}", newest.format("%H:%M:%S"));
    }

    // 10. 测试健康检查
    println!("\n=== 10. 健康检查 ===");
    storage.health_check().await?;
    println!("  ✅ 存储系统健康检查通过");

    println!("\n✅ 文件存储增强功能测试全部完成！");
    println!("\n💡 查看详细日志:");
    println!("   RUST_LOG=debug cargo run --example file_storage_test");
    
    Ok(())
}